home *** CD-ROM | disk | FTP | other *** search
/ Freaks Macintosh Archive / Freaks Macintosh Archive.bin / Freaks Macintosh Archives / Hacking & Misc / bundle of exploits.sit / bundle of exploits / udpscan.c < prev    next >
C/C++ Source or Header  |  1998-07-17  |  5KB  |  245 lines

  1. /* UDP scanner.
  2.    Please dont go around scanning the planet it isnt polite.
  3.  
  4.    We try and identify open UDP ports by sending a bogus UDP packet
  5.    then waiting for an ICMP message of "PORT UNREACHABLE".
  6.  
  7.    There are a few problems with this UDP scanner which I'll probably c0de up
  8.    to bypass. One bieng the fact that both ICMP and UDP get lost. I thought of
  9.    adding an RTT mechanism but that would be an overkill for a simple
  10.    example like this one. In the long run your better off using RTT if your 
  11.    doing it in a congested network.
  12.  
  13.    Since we're not using direct packet capturing on the
  14.    interace itself the kernel may or may not drop the packets before
  15.    passing them to all proccesses currently using SOCK_RAW and IPPROTO_ICMP.
  16.    A better implementation would use libpcap.
  17.  
  18.    I honestly have no idea if its been done before in the same way.
  19.  
  20.    Fri Sep 20 01:47:48 1996
  21.  
  22.    Copyleft 1996 shadows@whitefang.com
  23.                  shadows@kuwait.net
  24.  
  25.    Has been tested on FreeBSD 2.1.5
  26. */
  27.  
  28. #include <stdlib.h>
  29. #include <stdio.h>
  30. #include <sys/socket.h>
  31. #include <sys/types.h>
  32. #include <sys/time.h>
  33.  
  34. #include <netinet/in_systm.h>
  35. #include <netinet/in.h>
  36. #include <netinet/ip.h>
  37. #include <netinet/ip_icmp.h>
  38. #include <arpa/inet.h>
  39. #include <netdb.h>
  40. #include <unistd.h>
  41. #include <strings.h>
  42. #include <errno.h>
  43.  
  44. /* Tweak these to make things faster. I've included getopt as well
  45.    since I'm an option kinda guy ;) */
  46.  
  47. #define MAXPACKET 4096
  48. #define DEFAULT_TIMEOUT 10
  49. #define DEFAULT_RESEND 6
  50. #define SPORT 1
  51. #define EPORT 1024
  52.  
  53. extern char *optarg;
  54. extern int optind;
  55.  
  56. void usage(char *string)
  57. {
  58.   fprintf(stderr,"usage: %s hostname|ipaddr [-s start port] [-e end port] [-t timeout]\n",string);
  59.   exit(-1);
  60. }
  61.  
  62. void start_scanning(unsigned short sport,unsigned short eport,struct in_addr myaddr,unsigned short timeout,int maxretry)
  63. {
  64.   struct sockaddr_in myudp;
  65.   char buff[] = "This was a blatant UDP port scan.";
  66.   int udpsock, rawsock, retry, retval,iplen;
  67.   unsigned short port;
  68.   fd_set r;
  69.   struct timeval mytimeout;
  70.   struct icmp *packet;
  71.   struct ip *iphdr;
  72.   struct servent *service;
  73.   unsigned char recvbuff[MAXPACKET];
  74.  
  75.   if((udpsock = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP)) < 0)
  76.     {
  77.       perror("socket()");
  78.       exit(-1);
  79.     }
  80.  
  81.   if((rawsock = socket(AF_INET,SOCK_RAW,IPPROTO_ICMP)) < 0)
  82.     {
  83.       perror("socket()");
  84.       exit(-1);
  85.     }
  86.  
  87.   if(!(sport))
  88.     sport = SPORT;
  89.   if(!(eport))
  90.     eport = EPORT;
  91.   if(!(timeout))
  92.     timeout = DEFAULT_TIMEOUT;
  93.   if(!(maxretry))
  94.     maxretry = DEFAULT_RESEND;
  95.  
  96.   if(sport > eport)
  97.     {
  98.       fprintf(stderr,"Uh you've got the start-port at %u and the end-port at %u this doesnt look right.\n",sport,eport);
  99.       exit(-1);
  100.     }
  101.  
  102.   bcopy(&myaddr.s_addr,&myudp.sin_addr.s_addr,sizeof(myaddr.s_addr));
  103.  
  104.   myudp.sin_family = AF_INET;
  105.  
  106.   mytimeout.tv_sec = timeout;
  107.   mytimeout.tv_usec = 0;
  108.  
  109.   for(port = sport;port < eport;port++)
  110.     {
  111.       
  112.       myudp.sin_port = htons(port);
  113.       
  114.       retry = 0;
  115.     
  116.       while(retry++ < maxretry)
  117.     {
  118.       
  119.       /* I'll use select to do the timeout. Its a bit more
  120.          'portable'. Than using a signal */
  121.       
  122.       if((sendto(udpsock,buff,sizeof(buff),0x0,(struct sockaddr *)&myudp,sizeof(myudp))) < 0)
  123.         {
  124.           perror("sendto");
  125.           exit(-1);
  126.         }
  127.     
  128.  
  129.       FD_ZERO(&r);
  130.       FD_SET(rawsock,&r);
  131.       
  132.       retval = select((rawsock+1),&r,NULL,NULL,&mytimeout);
  133.       
  134.       if(retval)
  135.         {
  136.           /* We got an answer lets check if its the one we want. */
  137.       
  138.           if((recvfrom(rawsock,&recvbuff,sizeof(recvbuff),0x0,NULL,NULL)) < 0)
  139.         {
  140.           perror("Recv");
  141.           exit(-1);
  142.         }
  143.  
  144.           /* Problem with getting back the address of the host
  145.          is that not all hosts will answer icmp unreachable
  146.          directly from thier own host. */
  147.  
  148.           iphdr = (struct ip *)recvbuff;
  149.           iplen = iphdr->ip_hl << 2;
  150.           
  151.           packet = (struct icmp *)(recvbuff + iplen);
  152.  
  153.           if((packet->icmp_type == ICMP_UNREACH) && (packet->icmp_code == ICMP_UNREACH_PORT))
  154.             break;
  155.         
  156.         }
  157.       else
  158.         continue;
  159.     }
  160.  
  161.       if(retry >= maxretry)
  162.     {
  163.       if((service = getservbyport(htons(port),"udp")) == NULL)
  164.           fprintf(stdout,"Unknown port %u, open.\n",port);
  165.       else
  166.         fprintf(stdout,"UDP service %s open.\n",service->s_name);
  167.       fflush(stdout);
  168.     }
  169.     }
  170. }
  171.       
  172. struct in_addr resolv(char *address)
  173. {
  174.   struct in_addr myaddr;
  175.   struct hostent *host;
  176.  
  177.   if((myaddr.s_addr = inet_addr(address)) == INADDR_NONE)
  178.     {
  179.       if((host = gethostbyname(address)) == NULL)
  180.     fprintf(stderr,"%s Invalid address\n",address);
  181.       else
  182.     {
  183.       bcopy((int *) * &host->h_addr,&myaddr.s_addr,host->h_length); 
  184.       return myaddr;
  185.     }
  186.     }
  187.  
  188.     return myaddr;
  189. }
  190.  
  191.  
  192.  
  193. int main(int argc,char **argv)
  194. {
  195.   unsigned short sport = 0;
  196.   unsigned short eport = 0;
  197.   unsigned short timeout = 0;
  198.   unsigned short maxretry = 0;
  199.   struct in_addr myaddr;
  200.   char c;
  201.   
  202.   if(argc < 2)
  203.     {
  204.       usage(argv[0]);
  205.       exit(-1);
  206.     }
  207.  
  208.   while((c = getopt(argc,argv,"s:e:t:r:")) != EOF)
  209.     {
  210.       switch(c)
  211.     {
  212.     case 's':
  213.       {
  214.         sport = (unsigned int)atoi(optarg);
  215.         break;
  216.       }
  217.     case 'e':
  218.       {
  219.         eport = (unsigned int)atoi(optarg);
  220.         break;
  221.       }
  222.     case 't':
  223.       {
  224.         timeout = (unsigned int)atoi(optarg);
  225.         break;
  226.       }
  227.     case 'r':
  228.       {
  229.         maxretry = (unsigned int)atoi(optarg);
  230.         break;
  231.       }
  232.     default:
  233.       {
  234.         usage(argv[0]);
  235.       }
  236.     }
  237.     }
  238.  
  239.   myaddr = resolv(argv[optind]);
  240.  
  241.   start_scanning(sport,eport,myaddr,timeout,maxretry);
  242.  
  243.   exit(0);
  244. }
  245.